'''
@Description: In User Settings Edit
@Author: your name
@Date: 2019-08-21 11:43:26
@LastEditTime: 2019-12-05 13:55:42
@LastEditors: Please set LastEditors
'''
from ...service.common import insert_data, find_data, update_data, delete_data, get_condition, get_info
from ...pao_python.pao.service.data.mongo_db import MongoService, MongoFilter, C, N, F, as_date
from ...service.buss_pub.bill_manage import BillManageService, OperationType, TypeId, Status
from ...pao_python.pao.service.security.security_utility import get_current_account_id
from ...pao_python.pao.service.security.security_service import RoleService
import hashlib
import re
import datetime
import uuid
import pandas as pd
from ...pao_python.pao.data import process_db, dataframe_to_list, DataProcess, DataList
from ...service.mongo_bill_service import MongoBillFilter
# -*- coding: utf-8 -*-

'''
住宿区域函数
'''


class hotelZoneService(MongoService):
    def __init__(self, db_addr, db_port, db_name, db_user, db_pwd, inital_password, session):
        self.db_addr = db_addr
        self.db_port = db_port
        self.db_name = db_name
        self.db_user = db_user
        self.db_pwd = db_pwd
        self.inital_password = inital_password
        self.session = session
        self.bill_manage_server = BillManageService(
            self.db_addr, self.db_port, self.db_name, self.db_user, self.db_pwd, self.inital_password, self.session)

    def get_hotel_zone_list(self, org_list, condition, page, count):
        keys = ['zone_name', 'zone_number', 'organization_id', 'organization_type',
                'hotel_zone_type_id', 'upper_hotel_zone_id', 'remark', 'bed_id', 'id', 'hotel_zone_type_name', 'no_type_name']
        values = self.get_value(condition, keys)
        _filter = MongoBillFilter()
        # 左连接自己，原表 upper 对应右表id
        # 左连接组织，
        # 左连接区域类型，
        # 增加upper列，内容为upper_hotel_zone对象，筛选条件为bill_status == valid
        _filter = MongoBillFilter()
        _filter.inner_join_bill('PT_Hotel_Zone', 'upper_hotel_zone_id', 'id', 'upper_hotel_zone')\
            .inner_join_bill('PT_User', 'organization_id', 'id', 'organization')\
            .lookup_bill('PT_Hotel_Zone_Type', 'hotel_zone_type_id', 'id', 'type_info')\
            .match_bill((C('id') == values['id'])
                        & (C('zone_name').like(values['zone_name']))
                        & (C('zone_number').like(values['zone_number']))
                        & (C('organization_id').like(values['organization_id']))
                        & (C('upper_hotel_zone_id').like(values['upper_hotel_zone_id']))
                        & (C('remark').like(values['remark']))
                        & (C('organization_id').inner(org_list))
                        & (C('hotel_zone_type_name') == values['hotel_zone_type_name'])
                        & (C('hotel_zone_type_name') != values['no_type_name'])
                        & (C('organization.organization_info.personnel_category') == values['organization_type'])) \
            .add_fields({'organization_name': '$organization.name', 'organization_id': '$organization.id', 'upper_hotel_zone_id': '$upper_hotel_zone.id', 'upper_hotel_zone_name': '$upper_hotel_zone.zone_name'})\
            .project({
                '_id': 0,
                'upper_hotel_zone._id': 0,
                'organization._id': 0,
                'type_info._id': 0
            })
        res = self.page_query(_filter, 'PT_Hotel_Zone', page, count)
        return res

    def get_room_status_list(self, org_list, condition, page, count):
        collection_name = 'PT_Hotel_Zone'
        keys = ['is_none_user', 'room_type']
        values = self.get_value(condition, keys)
        a = ()
        if 'is_none_user' in condition:
            a = ((F('$bed_.bill_status') == 'valid') & (
                (F('$bed_.residents_id') == None) | (F('$bed_.residents_id') == '')))
        else:
            a = ((F('$bed_.bill_status') == 'valid'))
        _filter = MongoBillFilter()
        _filter\
            .match((C('bill_status') == 'valid')
                   & (C('organization_id').inner(org_list)))\
            .lookup_bill('PT_Hotel_Zone', 'upper_hotel_zone_id', 'id', 'upper_hotel_zone')\
            .lookup_bill('PT_Bed', 'id', 'area_id', 'bed_tmp')\
            .project({
                'bed_tmp._id': 0
            })\
            .add_fields({'upper': self.ao.array_filter('$upper_hotel_zone', 'up_', (F('$up_.bill_status') == 'valid').f)})\
            .add_fields({'bed': self.ao.array_filter('$bed_tmp', 'bed_', a.f)})\
            .add_fields({'bet_count': self.ao.size('$bed')})\
            .project({
                '_id': 0,
                'id': 1,
                'zone_name': 1,
                'zone_number': 1,
                'bed': 1,
                'hotel_zone_type_id': 1,
                'upper_hotel_zone_name': '$upper.zone_name',
                'upper_hotel_zone_id': '$upper.id',
                'hotel_zone_type_name': '$hotel_zone_type.name',
                'bet_count': '$bet_count'
            })\
            .sort({'zone_number': 1})\
            .lookup_bill('PT_User', 'bed.residents_id', 'id', 'user_tmp')\
            .add_fields({'user': self.ao.array_filter('$user_tmp', 'user_', (F('$user_.bill_status') == 'valid').f)})\
            .graph_lookup('PT_Hotel_Zone', '$upper_hotel_zone_id', 'upper_hotel_zone_id', 'id', 'upper_element')\
            .add_fields({'down_element': []})\
            .project({
                'upper_element._id': 0,
                'user._id': 0,
                'user_tmp': 0
            })
        if 'room_type' in condition.keys():
            _filter.match(((C('bet_count') == values['room_type']) | (C('bet_count') == 0)))\

        res = self.page_query(_filter, collection_name, None, None)

        return res

    def update_room_status(self, resident_source_id, bed_source_id, bed_dest_id):
        '''
            1、查出床源id（bed_source_id）对应数据
            2、查出床目的id（bed_dest_id）对应数据，取出床对应的长者id，并保存
            3、将源长者id（resident_source_id）修改进2查出的床位id
            4、将2中暂存的长者id存储进1中的长者id
        '''
        # 1、第一步
        collection_name = 'PT_Bed'
        _filter = MongoFilter()
        _filter\
            .match((C('bill_status') == 'valid') &
                   (C('id') == str(bed_source_id))
                   )
        bed_source = self.page_query(_filter, collection_name, None, None)

        # 2、第二步
        _filter = MongoFilter()
        _filter\
            .match((C('bill_status') == 'valid') &
                   (C('id') == str(bed_dest_id))
                   )
        bed_dest = self.page_query(_filter, collection_name, None, None)
        # 处理空床情况
        bed_dest_resident = None
        # 不用对bed_dest["result"][0]判空，在房态图中，床位一定存在，bed_dest['result'][0]同理
        if "residents_id" in bed_dest["result"][0].keys():
            bed_dest_resident = bed_dest['result'][0]['residents_id']

        # 3、第三步
        bed_dest['result'][0]['residents_id'] = resident_source_id

        # 4、第四步
        bed_source['result'][0]['residents_id'] = bed_dest_resident

        is_success_bed_source = self.bill_manage_server.add_bill(OperationType.update.value,
                                                                 TypeId.bed.value, bed_source['result'][0], 'PT_Bed')

        is_success_bed_dest = self.bill_manage_server.add_bill(OperationType.update.value,
                                                               TypeId.bed.value, bed_dest['result'][0], 'PT_Bed')

        self.res = 'Success' if is_success_bed_source and is_success_bed_dest else 'Fail'
        return self.res

    def update(self, hotel_zone):
        res = 'fail'

        def process_func(db):
            nonlocal res
            if 'id' in hotel_zone.keys():
                bill_id = self.bill_manage_server.add_bill(OperationType.update.value,
                                                           TypeId.hotelZone.value, hotel_zone, 'PT_Hotel_Zone')
                if bill_id:
                    res = 'Success'
            else:
                bill_id = self.bill_manage_server.add_bill(OperationType.add.value,
                                                           TypeId.hotelZone.value, hotel_zone, 'PT_Hotel_Zone')
                if bill_id:
                    res = 'Success'
        process_db(self.db_addr, self.db_port, self.db_name,
                   process_func, self.db_user, self.db_pwd)
        return res

    def del_hotel_zone(self, nursing_id_list):
        res = 'Fail'

        def process_func(db):
            nonlocal res
            for id in nursing_id_list:
                data = find_data(db, 'PT_Hotel_Zone', {
                    'id': id, 'bill_status': Status.bill_valid.value})
                if len(data) > 0:
                    self.bill_manage_server.add_bill(OperationType.delete.value,
                                                     TypeId.hotelZone.value, data[0], 'PT_Hotel_Zone')
            res = 'Success'
        process_db(self.db_addr, self.db_port, self.db_name,
                   process_func, self.db_user, self.db_pwd)
        return res
